﻿using DocumentFormat.OpenXml.Bibliography;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Business.HYT;
using NP.BPMReportPlatform.HYT.Dto;
using NP.BPMReportPlatform.MaterialMasterData.Dto;
using NP.BPMReportPlatform.RestfulApis.Dto;
using NP.BPMReportPlatform.Utilities;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.HYT
{
    public class HYTCHService : BPMReportPlatformAppService, IHYTCHService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform, _dbProcess;
        private readonly SqlSugarClient _dbEngine;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly INPRestHttpHelper _nPRestHttp;
        private readonly IExcelImporter _importer;
        private readonly string businessApiUrl;
        private readonly ILogger _logger;
        public HYTCHService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, INPRestHttpHelper nPRestHttp, IConfiguration configuration, 
            IExcelImporter importer, ILogger logger)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbProcess = sqlSugarAppService.GetProcessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _nPRestHttp = nPRestHttp;
            _importer = importer;
            businessApiUrl = configuration["BPM:BusinessApiUrl"];
            _logger = logger;
        }

        public async Task<PagedResultDto<HYTCHDto>> GetAllAsync(HYTInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x =>
            {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
            });
            //返回结果
            return new PagedResultDto<HYTCHDto>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<HYTCHDto>> ExportAsync(HYTInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<HYTCHDto> GetQueryable(HYTInput input)
        {
            var listQueryable = _db.Queryable<HYTCHHeader, BusinessProcessesNew>(
                    (x, b) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == b.InstanceId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, b) => x.InstanceNumber.Contains(input.InstanceNumber))
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, b) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), b.ProcessStatusCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, b) => b.StartUserName.Equals(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.AddTime >= input.StartCreationTime && x.AddTime.AddDays(-1) <= input.EndCreationTime)
                .WhereIF(input.SyncSuccess != null, x => x.SyncSuccess == input.SyncSuccess)
                .WhereIF(input.Status != null, x => x.Status == input.Status)
                .WhereIF(!string.IsNullOrEmpty(input.Factory), x => x.Factory == input.Factory)
                .WhereIF(!string.IsNullOrEmpty(input.OrderNumber), x => x.PurchaseOrder == input.OrderNumber)
                .WhereIF(input.IsSync != null, x => x.IsSync == input.IsSync)
                .Select((x, b) => new HYTCHDto
                {
                    Id = x.Id,
                    InstanceNumber = x.InstanceNumber,
                    AddTime = x.AddTime,
                    AddTimeStr = x.AddTime.ToString(DateFormatHelper.DateTimeFormat),
                    AddUserName = x.AddUserName,
                    Factory = x.Factory,
                    OriginNumber = x.OriginNumber,
                    IsSync = x.IsSync,
                    IsSyncStr = x.IsSync ? "是" : "否",
                    SyncResult = x.SyncResult,
                    SyncSuccess = x.SyncSuccess,
                    SyncSuccessStr = x.SyncSuccess ? "是" : "否",
                    Status = x.Status,
                    StatusStr = x.Status == 1 ? "是" : "否",
                    SyncCount = x.SyncCount,
                    OutType = x.OutType,
                    PurchaseOrder = x.PurchaseOrder,
                    OrderStatus = b.ProcessStatusName,
                    SyncTime = x.SyncTime,
                    SyncTimeStr = x.SyncTime != null ? x.SyncTime.Value.ToString(DateFormatHelper.DateTimeFormat) : ""
                }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc);
            return listQueryable;
        }

        public async Task<string> Eidt(HYTEditInput input)
        {
            var entity = await _db.Queryable<HYTCHHeader>().FirstAsync(x => x.Id == input.Id);
            if (entity == null)
            {
                throw new Exception("数据未找到");
            }

            entity.SyncSuccess = input.SyncSuccess;
            entity.SyncResult = input.SyncSuccess ? "处理成功" : entity.SyncResult;
            entity.Status = input.SyncSuccess ? 0 : input.Status;

            var flag = await _db.Updateable(entity).ExecuteCommandHasChangeAsync();
            return flag ? "保存成功" : "保存失败";
        }

        public async Task<ApiResultDto> ReSync(HYTReSyncInput input)
        {
            var result = await _nPRestHttp.PostAsync<ApiResultDto>(businessApiUrl + "HYT/AsyncHYTCHData", new Dictionary<string, string> { { "InstanceNumber", input.InstanceNumber } });
            _logger.Information($"{input.InstanceNumber},{JsonConvert.SerializeObject(result)}");
            return result;
        }

        /// <summary>
        /// 根据BPM单号获取出货详情，ESB接口
        /// </summary>
        /// <returns></returns>
        public async Task<List<GetBucketOutStockDetailDto>> GetBucketOutStockDetail(GetBucketOutStockDetailInput input)
        {
            if (string.IsNullOrWhiteSpace(input.instanceNumber))
            {
                return new List<GetBucketOutStockDetailDto>();
            }

            var listQueryable = _db.Queryable<HYTCHHeader, HYTCHDetail>((x, d) => x.InstanceNumber == d.InstanceNumber)
                .Where((x, d) => x.InstanceNumber == input.instanceNumber)
                .Select((x, d) => new GetBucketOutStockDetailDto
                {
                    Id = x.Id,
                    InstanceNumber = x.InstanceNumber,
                    Factory = x.Factory,
                    OutType = x.OutType ?? "",
                    BucketNumber = d.BucketNumber,
                    BucketName = d.BucketName,
                    BatchNumber = d.BatchNumber,
                    Inventory = d.Inventory,
                    Quantity = d.Quantity,
                    OutQuantity = d.OutQuantity,
                    Unit = d.Unit,
                    Dimension = d.Dimension,
                    SupplierCode = d.SupplierCode,
                    SupplierName = d.SupplierName,
                    Remark = d.Remark ?? "",
                }).MergeTable().Distinct();

            return await listQueryable.ToListAsync();
        }
    }
}
